package com.swsc.xapp.utils;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author YH_CK
 * @data 2018.09.14 14:25
 * @describe 图片处理工具类
 **/
public class ImageUtils {

    private static final String TAG = ImageUtils.class.getSimpleName();
    private static final int TYPE_TAKE_PHOTO = 2002;//Uri获取类型判断
    public static final int CODE_TAKE_PHOTO = 2002;//相机RequestCode
    public static String imagePath;
    public static String sdCardDirPath;//身份证截图存储位置

    /**
     * 打开系统相机
     *
     * @param context
     */
    public static void openCameraGetPhoto(Context context) {
        // 加载路径图片路径
        Uri photoUri = getMediaFileUri(TYPE_TAKE_PHOTO, null);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            takePhotoBiggerThan7(context, imagePath);
        } else {
            // 指定拍照意图
            Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // 指定存储路径，这样就可以保存原图了
            openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            ((Activity) context).startActivityForResult(openCameraIntent, CODE_TAKE_PHOTO);
        }
    }

    public static void openCameraGetPhoto(Context context, String bucket) {
        // 加载路径图片路径
        Uri photoUri = getMediaFileUri(TYPE_TAKE_PHOTO, bucket);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            takePhotoBiggerThan7(context, imagePath);
        } else {
            // 指定拍照意图
            Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            // 指定存储路径，这样就可以保存原图了
            openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            ((Activity) context).startActivityForResult(openCameraIntent, CODE_TAKE_PHOTO);
        }
    }

    /**
     * bitmap转为base64
     *
     * @param bitmapPath
     * @return
     */
    public static String bitmapToBase64(String bitmapPath) {
        int mQuality = 100;
        String result = null;
        ByteArrayOutputStream baos = null;
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 1;
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(bitmapPath, options);
        // Calculate inSampleSize
        // options.inSampleSize = calculateInSampleSize(options, 80, 80);
        // 修改照片比例 设置为固定值1/8
        options.inSampleSize = 2;
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeFile(bitmapPath, options);
        //获取图片的旋转角度，有些系统把拍照的图片旋转了，有的没有旋转
        int degree = readPictureDegree(bitmapPath);
        //把图片旋转为正的方向
        bitmap = ImageUtils.rotaingImage(degree, bitmap);
        try {
            if (bitmap != null) {
                long fileLen = getBitmapsize(bitmap);
                if (fileLen > 5 * 1024 * 1024) {
                    mQuality = 20;
                } else if (fileLen > 1024 * 1024) {
                    mQuality = 40;
                } else if (fileLen > 500 * 1024) {
                    mQuality = 60;
                } else if (fileLen > 100 * 1024) {
                    mQuality = 90;
                }
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, mQuality, baos);
                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = "data:image/png;base64," + Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                return "";
            }
        }
        return result;
    }

    /**
     * 压缩图片
     *
     * @param bitmapPath
     * @param imageSize
     * @param imageName
     * @return
     */
    public static String bitmapToSmall(String bitmapPath, String imageSize, String imageName) {
        FileOutputStream out = null;
        String sdCardDir = "";
        int mQualityMax = 100, mQualityMin = 0, mQuality = 100;
        Bitmap mBitmap = getBitmap(bitmapPath, 960, 1280);
        if (mBitmap == null) {
            return "";
        }
        //获取图片的旋转角度，有些系统把拍照的图片旋转了，有的没有旋转
        int degree = readPictureDegree(bitmapPath);
        //把图片旋转为正的方向
        mBitmap = ImageUtils.rotaingImage(degree, mBitmap);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (int i = 0; i < 8; i++) {
            mQuality = (mQualityMax + mQualityMin) / 2;
            baos.reset(); // 重置baos即清空baos
            mBitmap.compress(Bitmap.CompressFormat.JPEG, mQuality, baos);
            if (baos.toByteArray().length > Long.valueOf(imageSize) + 10240) {
                mQualityMax = mQuality;
            } else if (baos.toByteArray().length < Long.valueOf(imageSize)) {
                mQualityMin = mQuality;
            } else {
                break;
            }
        }

        // 判断是否可以对SDcard进行操作
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            // 获取SDCard指定目录下
            sdCardDir = Environment.getExternalStorageDirectory() + "/.XWFSmallPath";
            //目录转化成文件夹
            File dirFile = new File(sdCardDir);
            //如果不存在，那就建立这个文件夹
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }

            if (dirFile.isDirectory()) {
                try {
                    // 在SDcard的目录下创建图片,指定名称
                    File file = new File(sdCardDir, imageName);
                    out = new FileOutputStream(file);
                    mBitmap.compress(Bitmap.CompressFormat.JPEG, mQuality, out);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    return "";
                } finally {
                    try {
                        if (mBitmap != null) {
                            mBitmap.recycle();
                        }
                        if (out != null) {
                            out.flush();
                            out.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        return "";
                    }

                }
            } else {
                Log.i("ImageUtils", "failed to create directory!");
            }


        }
        return sdCardDir + "/" + imageName;
    }

    /**
     * Get bitmap from specified image path
     *
     * @param imgPath
     * @return
     */
    public static Bitmap getBitmap(String imgPath, int reqWidth, int reqHeight) {
        // Get bitmap through image path
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        // Do not compress
        newOpts.inSampleSize = 1;
        newOpts.inPreferredConfig = Bitmap.Config.RGB_565;
        BitmapFactory.decodeFile(imgPath, newOpts);
        // Calculate inSampleSize
        newOpts.inSampleSize = calculateInSampleSize(newOpts, reqWidth, reqHeight);
        // Decode bitmap with inSampleSize set
        newOpts.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(imgPath, newOpts);
    }

    /**
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            // Calculate ratios of height and width to requested height and
            // width
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will
            // guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? widthRatio : heightRatio;
        }

        return inSampleSize;
    }


    private static long getBitmapsize(Bitmap bitmap) {
            return bitmap.getByteCount();
    }

    /**
     * 将下载下来的图片保存到SD卡或者本地.并返回图片的路径(包括文件命和扩展名)
     *
     * @param context
     * @param bitName
     * @param mBitmap
     * @return
     */
    public static String saveBitmap(Context context, String bitName, Bitmap mBitmap) {
        String path = null;
        File f;
        if (mBitmap != null) {
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                f = new File(Environment.getExternalStorageDirectory() + File.separator + "images/");
                String fileName = Environment.getExternalStorageDirectory() + File.separator + "images/" + bitName + ".png";
                path = fileName;
                FileOutputStream fos = null;
                try {
                    if (!f.exists()) {
                        f.mkdirs();
                    }
                    File file = new File(fileName);
                    file.createNewFile();
                    fos = new FileOutputStream(file);
                    mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    fos.flush();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {

                    try {
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            } else {
                //本地存储路径
                f = new File(context.getFilesDir() + File.separator + "images/");
                Log.i(TAG, "本地存储路径:" + context.getFilesDir() + File.separator + "images/" + bitName + ".png");
                path = context.getFilesDir() + File.separator + "images/" + bitName + ".png";
                FileOutputStream fos = null;
                try {
                    if (!f.exists()) {
                        f.mkdirs();
                    }
                    File file = new File(path);
                    file.createNewFile();
                    fos = new FileOutputStream(file);
                    mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    fos.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }
        }

        return path;
    }

    /**
     * 读取图片属性：旋转的角度
     *
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /*
     * 旋转图片
     * @param angle
     * @param bitmap
     * @return Bitmap
     */
    public static Bitmap rotaingImage(int angle, Bitmap bitmap) {
        //旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
//        System.out.println("angle2=" + angle);
        // 创建新的图片
        return Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }

    /**
     * Android 7.0 及以上打开相机设置
     *
     * @param context
     * @param absolutePath
     */
    private static void takePhotoBiggerThan7(Context context, String absolutePath) {
        Uri mCameraTempUri;
        try {
            ContentValues values = new ContentValues(1);
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
            values.put(MediaStore.Images.Media.DATA, absolutePath);
            mCameraTempUri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            if (mCameraTempUri != null) {
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraTempUri);
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
            }
            ((Activity) context).startActivityForResult(intent, CODE_TAKE_PHOTO);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置拍照图片存储位置
     *
     * @param type
     * @param bucket
     * @return
     */
    public static Uri getMediaFileUri(int type, String bucket) {
        String imgDir = ConstantUils.DIR_INFRARED.concat(TextUtils.isEmpty(bucket) ? "0000/0000/" : bucket);
//        deleteImg(imgDir);
        // 删除历史图片
//        deleteImg(Environment.getExternalStorageDirectory() + File.separator + ".photosdk");
//        File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), ".photosdk");
        File mediaStorageDir = new File(imgDir);
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                return null;
            }
        }
        //创建Media File
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        imagePath = mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg";
        File mediaFile;
        if (type == TYPE_TAKE_PHOTO) {
            mediaFile = new File(imagePath);
        } else {
            return null;
        }
        return Uri.fromFile(mediaFile);
    }

    //删除历史图片
    public static void deleteImg(String path) {
        String folderPath = path;
        File dir = new File(folderPath);
        if (dir == null || !dir.exists() || !dir.isDirectory() || dir.listFiles() == null)
            return;
        for (File file : dir.listFiles()) {
            if (file.isFile())
                file.delete();
        }
    }

    public static boolean saveImage(Bitmap bitmap, String imageName) {
        String sdCardDir = "";
        FileOutputStream out = null;
        int mQuality = 100;
        if (bitmap == null) {
            return false;
        }
        long fileLen = getBitmapsize(bitmap);
        if (fileLen > 5 * 1024 * 1024) {
            mQuality = 20;
        } else if (fileLen > 1024 * 1024) {
            mQuality = 40;
        } else if (fileLen > 500 * 1024) {
            mQuality = 60;
        } else if (fileLen > 100 * 1024) {
            mQuality = 90;
        }
        // 判断是否可以对SDcard进行操作
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            // 获取SDCard指定目录下
            sdCardDir = Environment.getExternalStorageDirectory() + "/.yhcardImagePath/";
            //目录转化成文件夹
            File dirFile = new File(sdCardDir);
            //如果不存在，那就建立这个文件夹
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
            // 在SDcard的目录下创建图片文
            sdCardDirPath = sdCardDir;
            File file = new File(sdCardDir, imageName);
            try {
                out = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.JPEG, mQuality, out);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return false;
            }
            try {
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    /**
     * 将bmp转换为字节数组
     *
     * @param bmp
     * @param needRecycle
     * @return 微信分享专用
     */
    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {

        int i;
        int j;
        if (bmp.getHeight() > bmp.getWidth()) {
            i = bmp.getWidth();
            j = bmp.getWidth();
        } else {
            i = bmp.getHeight();
            j = bmp.getHeight();
        }

        Bitmap localBitmap = Bitmap.createBitmap(i, j, Bitmap.Config.RGB_565);
        Canvas localCanvas = new Canvas(localBitmap);

        while (true) {
            localCanvas.drawBitmap(bmp, new Rect(0, 0, i, j), new Rect(0, 0, i, j), null);
            if (needRecycle)
                bmp.recycle();
            ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
            localBitmap.compress(Bitmap.CompressFormat.JPEG, 100,
                    localByteArrayOutputStream);
            localBitmap.recycle();
            byte[] arrayOfByte = localByteArrayOutputStream.toByteArray();
            try {
                localByteArrayOutputStream.close();
                return arrayOfByte;
            } catch (Exception e) {
                //F.out(e);
            }
            i = bmp.getHeight();
            j = bmp.getHeight();
        }
    }

    /**
     * base64转图片
     * @param base64str base64码
     * @param savePath 图片路径
     * @return
     */
    public static boolean convertToImg(String base64str, String savePath) {
        //对字节数组字符串进行Base64解码并生成图片
        if (base64str == null) {
            return false;
        }
        byte[] decode = Base64.decode(base64str.split(",")[1], Base64.DEFAULT);
        Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
        try {
            FileOutputStream out = new FileOutputStream(savePath);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
        } catch (FileNotFoundException e) {

            e.printStackTrace();
            return false;
        }
        return true;
    }
    public static String getBase64ImageType(String base64Str) {
        String[] parts = base64Str.split(",");
        if (parts.length == 2) {
            String header = parts[0];
            if (header.startsWith("data:image/")) {
                return header.substring(11, header.indexOf(";"));
            } else if (header.startsWith("data:")) {
                return header.substring(5, header.indexOf(";"));
            }
        }

        // 读取Base64字符串的前4个字节
        byte[] bytes = Base64.decode(base64Str, Base64.DEFAULT);
        if (bytes.length >= 4) {
            byte b1 = bytes[0];
            byte b2 = bytes[1];
            byte b3 = bytes[2];
            byte b4 = bytes[3];
            if (b1 == (byte)0xFF && b2 == (byte)0xD8) {
                return "jpeg";
            } else if (b1 == (byte)0x89 && b2 == (byte)0x50 && b3 == (byte)0x4E && b4 == (byte)0x47) {
                return "png";
            } else if (b1 == (byte)0x47 && b2 == (byte)0x49 && b3 == (byte)0x46 && (b4 == (byte)0x37 || b4 == (byte)0x39)) {
                return "gif";
            } else if (b1 == (byte)0x42 && b2 == (byte)0x4D) {
                return "bmp";
            }
        }

        return null;
    }

}
